home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / invgamma.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  4KB  |  189 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    invgamma -
  19.  *        Invert arbitrary gamma look up tables.
  20.  *
  21.  *            Paul Haeberli - 1991
  22.  */
  23. #include "stdio.h"
  24. #include "math.h"
  25.  
  26. static makeinvtab();
  27.  
  28. #define TESTING
  29. #ifdef TESTING
  30. short mytab[256];
  31.  
  32. main()
  33. {
  34.     int i;
  35.  
  36.     fprintf(stderr,"mytab\n");
  37.     for(i=0; i<256; i++) {
  38.     mytab[i] = rand()%256;                /* for random ramp */
  39.     mytab[i] = 255.0*pow(i/255.0,0.5)+0.499;    /* for gamma 2.0 ramp*/
  40.     fprintf(stderr,"%3d ",mytab[i]);
  41.     }
  42.     fprintf(stderr,"\n");
  43.     newgammaramp(mytab,mytab,mytab);
  44. }
  45. #endif
  46.  
  47. #define TABSIZE    (256)
  48.  
  49. static short rtab[TABSIZE];
  50. static short gtab[TABSIZE];
  51. static short btab[TABSIZE];
  52. static short irtab[TABSIZE];
  53. static short igtab[TABSIZE];
  54. static short ibtab[TABSIZE];
  55.  
  56. newgammaramp(r,g,b)
  57. short r[TABSIZE], g[TABSIZE], b[TABSIZE];
  58. {
  59.     bcopy(r,rtab,TABSIZE*sizeof(short));
  60.     bcopy(g,gtab,TABSIZE*sizeof(short));
  61.     bcopy(b,btab,TABSIZE*sizeof(short));
  62.     makeinvtab(rtab,irtab);
  63.     makeinvtab(gtab,igtab);
  64.     makeinvtab(btab,ibtab);
  65. }
  66.  
  67. static short *randorder;
  68. static short order[TABSIZE];
  69. static short *sortdata;
  70.  
  71. static int cmpfunc(v1,v2)
  72. short *v1, *v2;
  73. {
  74.    int i1, i2;
  75.  
  76.    i1 = sortdata[*v1];
  77.    i2 = sortdata[*v2];
  78.    if(i1<i2)
  79.       return -1;
  80.    if(i1>i2)
  81.       return 1;
  82.    if(*v1<*v2)
  83.       return -1;
  84.    if(*v1>*v2)
  85.       return 1;
  86.    return 0;
  87. }
  88.  
  89. static int delta(a,b)
  90. {
  91.    int d;
  92.  
  93.    d = a-b;
  94.    if(d>0)
  95.        return d;
  96.    else
  97.        return -d;
  98.  
  99. }
  100.  
  101. static makeinvtab(tab,itab)
  102. short tab[TABSIZE], itab[TABSIZE];
  103. {
  104.     int i, pos, temp;
  105.     int start, inpos, below, above;
  106.  
  107. /* make randomized order table if we must */
  108.     if(!randorder) {
  109.     randorder = (short *)mymalloc(TABSIZE*sizeof(short));
  110.     for(i=0; i<TABSIZE; i++)
  111.         randorder[i] = i;
  112.     for(i=0; i<TABSIZE; i++) {
  113.         pos = i+rand()%(TABSIZE-i);
  114.         temp = randorder[pos];
  115.         randorder[pos] = randorder[i];
  116.         randorder[i] = temp;
  117.     }
  118.     }
  119. /* start with randomized order so qsort will run fast */
  120.     bcopy(randorder,order,TABSIZE*sizeof(short));
  121.  
  122. /* sort the table into increasing order */
  123.     sortdata = tab;
  124.     qsort(order,TABSIZE,sizeof(short),cmpfunc);
  125.  
  126. /* make the inverse table */
  127.     start = 0;
  128.     for(i=0; i<TABSIZE; i++) {
  129.     inpos = start;
  130.     while(inpos<256) {
  131.         if(tab[order[inpos]]<=i) {
  132.         above = below = order[inpos];
  133.         start = inpos;
  134.         }
  135.         if(tab[order[inpos]]>=i) {
  136.         above = order[inpos];
  137.         break;
  138.         }
  139.         inpos++;
  140.     }
  141.     if(delta(i,tab[below])<delta(i,tab[above]))
  142.         itab[i] = below;
  143.     else
  144.         itab[i] = above;
  145.     }
  146.  
  147. #ifdef TESTING
  148. /* print the inverse table */
  149.     fprintf(stderr,"inverse\n");
  150.     for(i=0; i<TABSIZE; i++) 
  151.     fprintf(stderr,"%3d ",itab[i]);
  152.     fprintf(stderr,"\n");
  153.  
  154. /* print the result table */
  155.     fprintf(stderr,"result\n");
  156.     for(i=0; i<TABSIZE; i++) 
  157.     fprintf(stderr,"%3d ",tab[itab[i]]);
  158.     fprintf(stderr,"\n");
  159. #endif
  160. }
  161.  
  162. /*
  163.  *    toguns -
  164.  *        takes an rgb triple 0..255 and translates it to gun
  165.  *        rgb triple 0..255
  166.  *
  167.  */
  168. toguns(r,g,b,rgun,ggun,bgun)
  169. int r, g, b, *rgun, *ggun, *bgun;
  170. {
  171.     *rgun = rtab[r];
  172.     *ggun = gtab[g];
  173.     *bgun = btab[b];
  174. }
  175.  
  176. /*
  177.  *    fromguns -
  178.  *        takes a gun rgb triple 0..255 and translates it to an
  179.  *        rgb triple 0..255
  180.  *
  181.  */
  182. fromguns(rgun,ggun,bgun,r,g,b)
  183. int rgun, ggun, bgun, *r, *g, *b;
  184. {
  185.     *r = irtab[rgun];
  186.     *g = igtab[ggun];
  187.     *b = ibtab[bgun];
  188. }
  189.